#ifndef FUNCTIONS
#define FUNCTIONS
#include<string>

struct Function {
	virtual double value(double x) const=0;
        virtual ~Function();
};

struct Var : Function {
    double value(double x) const;
};

struct Const : Function {
    Const();
    Const(std::string function);
    double value(double x) const;
private:
    double number_;
};

struct CompositeFunction : Function {
    CompositeFunction();
    CompositeFunction(Function * left, Function * right);
    CompositeFunction(CompositeFunction const & copy);
    CompositeFunction & operator=(CompositeFunction const & right);
    ~CompositeFunction();
    double value(double x) const =0;
protected:
    Function * left_;
    Function * right_;
private:
    int * copy_counter_;
};

struct Plus : public CompositeFunction {
    Plus();
    Plus(Function * left, Function * right);
    Plus(Plus const & copy);
    double value(double x) const;
};

struct Minus : CompositeFunction {
    Minus();
    Minus(Function * left, Function * right);
    Minus(Minus const & copy);
    double value(double x) const;
};

struct Mult : CompositeFunction {
    Mult();
    Mult(Function * left, Function * right);
    Mult(Mult const & copy);
    double value(double x) const;
};

struct Devide : CompositeFunction {
    Devide();
    Devide(Function * left, Function * right);
    Devide(Devide const & copy);
    double value(double x) const;
};

#endif